/*
xp_adc.c
offer adc port function
designed by lunanting

-------------------------
2022-01-10 13:10:47
create file
*/

#include "xp_adc.h"
#include "aos/hal/adc.h"
#include "stdlib.h"
#include "cli_cmd.h"


#define ADC_FULL_V 10.0

static ADC *adc_obj=NULL;

static float xp_adc_default_convert(int value);

/*
init adc module
param:
    num: adc channel number, start 0 ~...
return:
    0=success
*/
int  xp_adc_init(int num){
    adc_dev_t adc={
        .port=0,
        .config=10,
        .priv=NULL
    };
    int sta=0;

    sta=hal_adc_init(&adc);
    if(sta!=0){
        goto ERR;
    }
    adc_obj=(ADC*)malloc(sizeof(ADC)*num);
    memset(adc_obj,0,sizeof(ADC)*num);
    adc_obj->init=1;
    adc_obj->num=num;
    println("adc init success !");
    return 0;

ERR:
    perr("adc init fail !");
    return -1;
}



/*
regist convert api
param:
    channel: regist channel 
    api: convert function
return:
    0=success
*/
int xp_adc_regist_api(ADC_channel channel,float (*api)(u32)){
    if(adc_obj==NULL||adc_obj->init!=1){
        perr("adc regist fail, adc no init~");
        return -1;
    }
    if(channel<adc_channel_0||channel>adc_channel_all||(channel>=adc_obj->num&&channel!=adc_channel_all)){
        perr("adc regist fail, input channel error !");
        return -2;
    }
    if(channel==adc_channel_all){
        for(int i=0;i<adc_obj->num;i++){
            adc_obj[i].data.value_convert=api;
        }
    }
    else{
        adc_obj[channel].data.value_convert=api;
    }
    return 0;
}


/*
get adc data
连续执行，需要间隔ms级时间
param:
    channel: adc channel
return:
    adc data pointer ADC_data
    NULL=fail
*/
ADC_data *xp_adc_data_get(ADC_channel channel){
    int try=0;
    adc_dev_t adc={
        .port=channel,
        .config=10,
        .priv=NULL
    };

    if(adc_obj==NULL||adc_obj->init!=1){
        perr("adc data get fail, adc no init~");
        return NULL;
    }
    if(channel<adc_channel_0||channel>adc_channel_all||(channel>=adc_obj->num&&channel!=adc_channel_all)){
        perr("adc data get fail, input channel error !");
        return NULL;
    }
    while(hal_adc_value_get(&adc,&adc_obj[channel].data.value,100)!=0){
        try++;
        if(try>20){
            break;
        }
    }

    if(adc_obj[channel].data.value_convert!=NULL){
        adc_obj[channel].data.data=adc_obj[channel].data.value_convert(adc_obj[channel].data.value);
    }
    else{
        adc_obj[channel].data.data=xp_adc_default_convert(adc_obj[channel].data.value);
    }
    return &(adc_obj[channel].data);
}



/*
default convert api
*/
static float xp_adc_default_convert(int value){
    u32 v=value;
    float f=0.0;

    f=v/4096.0*ADC_FULL_V;
    return f;
}

//end of the file
